<template>
    <u-popup :show="show" round="16rpx" mode="center" :customStyle="modal_style" :closeOnClickOverlay="false" :safeAreaInsetBottom="false">
        <slot name="header">
            <view v-if="titleIcon" class="ayy-title-icon">
                <image :style="title_icon_style" :src="titleIcon" mode="widthFix"></image>
            </view>
            <view v-if="title" :style="title_style" class="ayy-title">
                <text>{{ title }}</text>
            </view>
            <view v-else style="height: 24rpx"></view>
        </slot>
        <view class="ayy-popup-content">
            <slot>
                <view v-if="content" :style="content_style" class="ayy-content">
                    <text v-if="contentMode == 'text'">{{ content }}</text>
                    <rich-text v-else-if="contentMode == 'rich-text'" :nodes="content"></rich-text>
                    <u-parse v-else-if="contentMode == 'html'" :scrollTable="true" :content="content" :lazyLoad="true" :useAnchor="true"></u-parse>
                </view>

                <!-- 多行输入|单行输入 -->
                <template v-if="editable">
                    <template v-if="inputMode == 'input'">
                        <view class="ayy-input-view">
                            <input placeholder-style="fontSize: 28rpx" v-model="inputText" :placeholder="placeholderText" />
                        </view>
                    </template>
                    <template v-else>
                        <view class="ayy-textarea-view">
                            <textarea class="ayy-textarea" v-model="inputText" :placeholder="placeholderText" maxlength="-1" confirm-type="done" />
                        </view>
                    </template>
                </template>
            </slot>
        </view>
        <slot name="footer">
            <view class="ayy-footer">
                <text v-if="showCancel" :style="cancel_style" class="ayy-btn" @click="cancelAction">{{ cancelText || '取消' }}</text>
                <text class="ayy-btn" :style="confirm_style" @click="confirmAction">{{ confirmText || '确定' }}</text>
            </view>
        </slot>
    </u-popup>
</template>

<script>
import util from './util.js'
export default {
    name: 'jp-modal',
    data() {
        return {
            key: null, //唯一标识（不传会自动生成）
            show: false,
            titleIcon: null, //标题顶部图标
            title: null,
            content: null,
            showCancel: true,
            cancelText: '取消',
            confirmText: '确定',

            editable: false, //是否显示输入框
            inputMode: 'input', //input | textarea
            placeholderText: '请输入',
            inputText: null,

            modalStyle: null,
            contentMode: 'text', //text、rich-text、html
            cancelColor: null,
            confirmColor: null,
            titleIconStyle: null,
            titleStyle: null,
            contentStyle: null,
            cancelStyle: null,
            confirmStyle: null,

            // App端,如果定义了函数回调,需要显示的在这里定义一下函数名称
            closeModalFun: null,
            confirmFun: null,
            cancelFun: null
        }
    },
    // #ifdef APP
    onLoad() {
        this.show = false
        uni.$on('updateJpModalData', data => {
            Object.keys(this.$data).forEach(vmKey => {
                let hasVmKey = false
                Object.keys(data).forEach(key => {
                    this.$data[key] = data[key]
                    if (key === vmKey) {
                        hasVmKey = true
                    }
                })
                if (!hasVmKey) {
                    this.$data[vmKey] = null
                }
            })
            this.show = true
        })

        if (process.env.NODE_ENV === 'development') {
            //真机调试停留在此页面重新热更新，会重新调用onLoad，导致白屏
            setTimeout(() => {
                if (this.key == null) {
                    uni.navigateBack()
                }
            }, 500)
        }
    },
    destroyed() {
        uni.$jpModal.removeAll()
        uni.$off('updateJpModalData')
    },
    onBackPress(options) {
        if (options.from == 'backbutton') {
            return true
        }
        return false
    },
    // #endif
    // #ifdef MP
    mounted() {
        uni.$jpModal.initInstance(this)
    },
    beforeDestroy() {
        uni.$jpModal.removeAll()
        uni.$jpModal.removeInstance(this)
    },
    // #endif

    computed: {
        title_icon_style() {
            if (this.titleIconStyle) {
                if (this.titleIconStyle instanceof Object) {
                    return uni.$u.addStyle(this.titleIconStyle, 'string')
                } else {
                    return this.titleIconStyle
                }
            }
            return ''
        },
        title_style() {
            if (this.titleStyle) {
                if (this.titleStyle instanceof Object) {
                    return uni.$u.addStyle(this.titleStyle, 'string')
                } else {
                    return this.titleStyle
                }
            }
            return ''
        },
        content_style() {
            if (this.contentStyle) {
                if (this.contentStyle instanceof Object) {
                    return uni.$u.addStyle(this.contentStyle, 'string')
                } else {
                    return this.contentStyle
                }
            }
            return ''
        },
        cancel_style() {
            //cancelColor优先于cancelStyle
            if (this.cancelColor) {
                return `color:${this.cancelColor};`
            }
            if (this.cancelStyle) {
                if (this.cancelStyle instanceof Object) {
                    return uni.$u.addStyle(this.cancelStyle, 'string')
                } else {
                    return this.cancelStyle
                }
            }
            return `color:${uni.$jpModal.config.cancelColor};`
        },
        confirm_style() {
            //confirmColor优先于confirmStyle
            if (this.confirmColor) {
                return `color:${this.confirmColor};`
            }
            if (this.confirmStyle) {
                if (this.confirmStyle instanceof Object) {
                    return uni.$u.addStyle(this.confirmStyle, 'string')
                } else {
                    return this.confirmStyle
                }
            }
            return `color:${uni.$jpModal.config.confirmColor};`
        },
        modal_style() {
            if (util.empty(this.modalStyle)) {
                this.modalStyle = {
                    overflow: 'hidden'
                }
            } else if (util.empty(this.modalStyle.overflow)) {
                this.modalStyle.overflow = 'hidden'
            }

            if (this.editable) {
                this.modalStyle.transform = 'translateY(-30%)'
            }
            return this.modalStyle
        }
    },
    watch: {
        show: {
            handler(e) {
                // #ifdef H5
                //使用组件时，会发现内容部分滚动到底时，继续划动会导致底层页面的滚动，这就是滚动穿透。
                //但由于平台自身原因，除了h5平台外 ，其他平台都不能在在 组件内 禁止滚动穿透，
                //所以在微信小程序、App 平台，页面内需要用户特殊处理一下（<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>）
                //https://uniapp.dcloud.net.cn/component/uniui/uni-popup.html#禁止滚动穿透
                document.body.style.overflow = e == true ? 'hidden' : 'auto'
                // #endif
                this.$nextTick(() => {
                    // #ifdef MP
                    if (e) {
                        uni.hideTabBar()
                    } else {
                        uni.showTabBar()
                    }
                    // #endif
                })
            },
            deep: true
        }
    },
    methods: {
        cancelAction() {
            if (this.editable) {
                this.inputText = ''
            }
            this.closeModal()
        },
        async confirmAction() {
            if (this.confirmFun && typeof this.confirmFun === 'function') {
                let data = JSON.parse(JSON.stringify(this.$data))
                //删除无用节点
                Object.keys(data).forEach(key => {
                    if (data[key] == null) {
                        delete data[key]
                    }
                })

                let flag = await this.confirmFun.call(uni.$u.$parent.call(this), data)
                if (flag == false) {
                    console.log(`【jp-modal】弹窗关闭被拦截（不允许关闭）`)
                    return
                }
            }
            this.closeModal()
        },
        closeModal() {
            if (this.closeModalFun && typeof this.closeModalFun === 'function') {
                this.closeModalFun.call(uni.$u.$parent.call(this))
            }
        }
    }
}
</script>

<style>
body,
page {
    background: transparent !important;
}
</style>

<style lang="scss" scoped>
.ayy-title-icon {
    display: flex;
    flex-direction: row;
    justify-content: center;

    image {
        width: 80rpx;
        height: 80rpx;
        margin-top: 24rpx;
    }
}

.ayy-title {
    display: flex;
    flex-direction: row;
    justify-content: center;
    font-size: 34rpx;
    font-weight: bold;
    padding: 24rpx 32rpx;
}

.ayy-popup-content {
    width: 550rpx;
    overflow-y: scroll;
}
.ayy-content {
    display: flex;
    flex-direction: column;
    max-height: 60vh;
    font-size: 32rpx;
    line-height: 1.4;
    padding: 0 32rpx 32rpx 32rpx;
}

.ayy-input-view {
    display: flex;
    flex-direction: row;
    padding: 0 24rpx 32rpx 24rpx;

    input {
        flex: 1;
        font-size: 28rpx;
        line-height: 32rpx;
        padding: 0 24rpx;
        height: 75rpx;
        border-radius: 8rpx;
        border: 2rpx rgba(0, 0, 0, 0.1) solid;
    }
}

.ayy-textarea-view {
    height: 200rpx;
    margin: 0 24rpx 32rpx 24rpx;
    padding: 16rpx;
    border-radius: 8rpx;
    background: #f7f8fa;

    .ayy-textarea {
        width: 100%;
        height: 100%;
        font-size: 28rpx;
    }
}

.ayy-footer {
    display: flex;
    flex-direction: row;

    .ayy-btn {
        flex: 1;
        padding: 20rpx 0;
        font-size: 32rpx;
        /* #ifdef H5 */
        border-top: 2rpx rgba(0, 0, 0, 0.1) solid;
        border-left: 2rpx rgba(0, 0, 0, 0.1) solid;
        /* #endif */
        /* #ifndef H5 */
        border-top: 1rpx rgba(0, 0, 0, 0.1) solid;
        border-left: 1rpx rgba(0, 0, 0, 0.1) solid;
        /* #endif */
        text-align: center;

        &:first-child {
            border-left: none;
        }
    }
}
</style>
